package multiplex.dataaccess.dao;

import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import multiplex.dataaccess.DaoException;
import multiplex.model.Filme;

public class FilmeDao extends AbstractDao{
	
	public Filme get(int id) throws DaoException {
		try{
			PreparedStatement st = getConnection().prepareStatement("SELECT * FROM Filme WHERE id =?");
			st.setInt(1, id);		
			ResultSet rs = st.executeQuery();
			if(rs.next()){
				Filme filme = new Filme();
				fillFilme(filme, rs);
				st.close();
				return filme;
			}
		} catch(Exception e){
			throw new DaoException(e);
		}
		return null;
	}

	public List<Filme> getAll() throws DaoException {
		List<Filme> filmeList = new ArrayList<Filme>();
		try{
			PreparedStatement st = getConnection().prepareStatement("SELECT * FROM Filme");
			ResultSet rs = st.executeQuery();
			while(rs.next()){
				Filme filme = new Filme();
				fillFilme(filme, rs);
				filmeList.add(filme);
			}
			st.close();
			return filmeList;
		}catch(Exception e){
			throw new DaoException(e);
		}
	}
	
	public List<String> getCidades() throws DaoException {
		List<String> cidadeList = new ArrayList<String>();
		try{
			PreparedStatement st = getConnection().prepareStatement("select cidade from localizacao group by cidade");
			
			ResultSet rs = st.executeQuery();
			while(rs.next()){
				String cidade = rs.getString("cidade");
				cidadeList.add(cidade);
			}
			st.close();
			return cidadeList;
		}catch(Exception e){
			throw new DaoException(e);
		}
	}
	
	public List<Filme> getAllOrderByName() throws DaoException {
		List<Filme> filmeList = new ArrayList<Filme>();
		try{
			PreparedStatement st = getConnection().prepareStatement("SELECT * FROM Filme ORDER BY nome");
			ResultSet rs = st.executeQuery();
			while(rs.next()){
				Filme filme = new Filme();
				fillFilme(filme, rs);
				filmeList.add(filme);
			}
			return filmeList;
		}catch(Exception e){
			throw new DaoException(e);
		}
	}

	public void save(Filme filme) throws DaoException {
		try{
			PreparedStatement st = getConnection().prepareStatement(
					"INSERT INTO Filme (nome, nomeOriginal, distribuidora, produtores, " +
					"elenco, localProducao, url, tipoFilme, ano, duracao, destaque, " +
					"indicacaoEtaria, direcao) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", Statement.RETURN_GENERATED_KEYS);
			fillPreparatedStatement(st, filme);
			st.execute();
			ResultSet rs = st.getGeneratedKeys();
			rs.next();
			filme.setId(rs.getInt(1));
			st.close();
		}catch(Throwable e){
			throw new DaoException(e);
		}
	}
	
	public void update(Filme filme) throws DaoException {
		try{
			PreparedStatement st = getConnection().prepareStatement(
					"UPDATE Filme SET nome=?, nomeOriginal=?, distribuidora=?, produtores=?, " +
					"elenco=?, localProducao=?, url=?, tipoFilme=?, ano=?, duracao=?, destaque=?, " +
					"indicacaoEtaria=?, direcao=? WHERE id=?");				
			fillPreparatedStatement(st, filme);
			st.setInt(14, filme.getId());
			st.execute();
			st.close();
		}catch(Throwable e){
			throw new DaoException(e);
		}
	}

	public void remove(Filme filme) throws DaoException {
		try{
			PreparedStatement st = getConnection().prepareStatement(
					"DELETE FROM Filme WHERE id=? ");
			st.setInt(1, filme.getId());
			st.execute();
			st.close();		
		}catch(Throwable e){
			throw new DaoException(e);
		}	
	}
	
	private void fillFilme(Filme filme, ResultSet rs) throws SQLException {
		Calendar calendar = Calendar.getInstance();
		filme.setId(rs.getInt("id"));
		filme.setNome(rs.getString("nome"));
		filme.setNomeOriginal(rs.getString("nomeOriginal"));
		filme.setDistribuidora(rs.getString("distribuidora"));
		filme.setProdutores(rs.getString("produtores"));
		filme.setElenco(rs.getString("elenco"));
		filme.setLocalProducao(rs.getString("localProducao"));
		filme.setSite(rs.getString("url"));
		filme.setTipoFilme(rs.getString("tipoFilme"));
		calendar.setTime(rs.getDate("ano"));
		filme.setAno(calendar);
		filme.setDuracao(rs.getInt("duracao"));
		filme.setDestaque(rs.getBoolean("destaque"));
		filme.setIndicacaoEtaria(rs.getInt("indicacaoEtaria"));
		filme.setDirecao(rs.getString("direcao"));
	}
	
	private void fillPreparatedStatement(PreparedStatement st, Filme filme) throws SQLException {
		st.setString(1,filme.getNome());
		st.setString(2,filme.getNomeOriginal());
		st.setString(3,filme.getDistribuidora());
		st.setString(4, filme.getProdutores());
		st.setString(5, filme.getElenco());
		st.setString(6, filme.getLocalProducao());
		st.setString(7, filme.getSite());
		st.setString(8, filme.getTipoFilme());
		st.setDate(9, new  Date(filme.getAno().getTimeInMillis()));
		st.setInt(10, filme.getDuracao());
		st.setBoolean(11,filme.isDestaque());
		st.setInt(12, filme.getIndicacaoEtaria());
		st.setString(13, filme.getDirecao());
	}
	
}
